package org.hentor.modules.generate.generate.dbGenerate;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hentor.modules.generate.dto.GenerateDbDTO;
import org.hentor.modules.generate.generate.enums.GenerateModelType;
import org.hentor.modules.generate.generate.enums.GenerateMysqlType;
import org.hentor.generate.entity.GenerateDevDetail;
import org.hentor.generate.entity.GenerateDevMain;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class MysqlGenerateDb extends AbstractDbGenerate {
    @Override
    public List<String> generate(GenerateDbDTO generateDbDTO) {
        List<String> sqlList = new ArrayList<>();
        List<GenerateDevDetail> generateDevDetailList = generateDbDTO.getGenerateDevDetailList();
        if(GenerateModelType.CREATE_TABLE.getCode().equals(generateDbDTO.getModel())){
            //创建表
            sqlList.add(creteTable(generateDbDTO));
        }else if(GenerateModelType.UPDATE_TABLE_COMMENT.getCode().equals(generateDbDTO.getModel())){
            //修改备注
            sqlList.add("ALTER TABLE " + generateDbDTO.getGenerateDevMain().getTableName() + " COMMENT = " + "'" + generateDbDTO.getGenerateDevMain().getTableDescription() + "'" + ";");
        }else if(GenerateModelType.CREATE_PRIMARY_KEY.getCode().equals(generateDbDTO.getModel())){
            //修改主键
            List<String> primaryKeyList = generateDevDetailList.stream().filter(x -> StringUtils.isNotBlank(x.getColumnName()) && 1 == x.getPrimaryKey()).sorted(Comparator.comparing(GenerateDevDetail::getSortOrder)).map(GenerateDevDetail::getColumnName).collect(Collectors.toList());
            StringBuilder primaryKeyBuilder = new StringBuilder();
            if(CollectionUtils.isNotEmpty(primaryKeyList)){
                primaryKeyList.forEach(x->{
                    primaryKeyBuilder.append("`").append(x).append("`,");
                });
                primaryKeyBuilder.deleteCharAt(primaryKeyBuilder.length() -1);
                sqlList.add("ALTER TABLE "+ generateDbDTO.getGenerateDevMain().getTableName()+" ADD PRIMARY KEY (" + primaryKeyBuilder +");");
            }

        }else if(GenerateModelType.DELETE_PRIMARY_KEY.getCode().equals(generateDbDTO.getModel())){
            //删除表主键
            sqlList.add("ALTER TABLE "+ generateDbDTO.getGenerateDevMain().getTableName()+" DROP PRIMARY KEY;");
        }else if(GenerateModelType.UPDATE_COLUMN_NAME.getCode().equals(generateDbDTO.getModel())){
            //修改表字段
            sqlList.addAll(updateColumnName(generateDbDTO));
        }else if(GenerateModelType.UPDATE_COLUMN_TYPE.getCode().equals(generateDbDTO.getModel())){
            //按顺序拼接
            generateDevDetailList.stream().sorted(Comparator.comparing(GenerateDevDetail::getSortOrder)).forEachOrdered(x->{
                //修改字段信息
                StringBuilder stringBuilder = new StringBuilder();
                //列名
                stringBuilder.append("`").append(x.getColumnName()).append("`").append(" ");
                //有小数点单独判断
                if(GenerateMysqlType.doubleType.getCode().equals(x.getColumnType()) || GenerateMysqlType.BigDecimalType.getCode().equals(x.getColumnType())){
                    stringBuilder.append(GenerateMysqlType.getDescByCode(x.getColumnType())).append("(").append(x.getColumnLength()).append(",").append(x.getColumnPoint()).append(")").append(" ");
                }else {
                    stringBuilder.append(GenerateMysqlType.getDescByCode(x.getColumnType())).append("(").append(x.getColumnLength()).append(")").append(" ");
                }
                //是否可为空
                if(x.getIsNull() != 1){
                    stringBuilder.append("NOT NULL ");
                }
                //默认值
                if(StringUtils.isNotBlank(x.getColumnDef())){
                    stringBuilder.append("DEFAULT '").append(x.getColumnDef()).append("' ");
                }
                //列注释
                stringBuilder.append("COMMENT '").append(x.getColumnDesc()).append("'");
                sqlList.add("ALTER TABLE "+ generateDbDTO.getGenerateDevMain().getTableName() +" MODIFY " +stringBuilder +";");
            });
        }
        return sqlList;
    }

    /**
     * 创建表ddl
     * @param generateDbDTO
     * @return
     */
    private String creteTable(GenerateDbDTO generateDbDTO){
        GenerateDevMain generateDevMain = generateDbDTO.getGenerateDevMain();
        List<GenerateDevDetail> generateDevDetailList = generateDbDTO.getGenerateDevDetailList();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("CREATE TABLE ");
        //表名
        stringBuilder.append(generateDevMain.getTableName());
        stringBuilder.append("(");
        //按顺序拼接
        generateDevDetailList.stream().sorted(Comparator.comparing(GenerateDevDetail::getSortOrder)).forEachOrdered(x->{
            //列名
            stringBuilder.append(x.getColumnName()).append(" ");
            //有小数点单独判断
            if(GenerateMysqlType.doubleType.getCode().equals(x.getColumnType()) || GenerateMysqlType.BigDecimalType.getCode().equals(x.getColumnType())){
                stringBuilder.append(GenerateMysqlType.getDescByCode(x.getColumnType())).append("(").append(x.getColumnLength()).append(",").append(x.getColumnPoint()).append(")").append(" ");
            }else {
                stringBuilder.append(GenerateMysqlType.getDescByCode(x.getColumnType())).append("(").append(x.getColumnLength()).append(")").append(" ");
            }
            //是否可为空
            if(x.getIsNull() != 1){
                stringBuilder.append("NOT NULL ");
            }
            //默认值
            if(StringUtils.isNotBlank(x.getColumnDef())){
                stringBuilder.append("DEFAULT '").append(x.getColumnDef()).append("' ");
            }
            //列注释
            stringBuilder.append("COMMENT '").append(x.getColumnDesc()).append("', ");
        });
        //获取主键
        List<String> primaryKeyList = generateDevDetailList.stream().filter(x -> 1 == x.getPrimaryKey()).map(GenerateDevDetail::getColumnName).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(primaryKeyList)){
            stringBuilder.append("PRIMARY KEY (");
            primaryKeyList.forEach(x->{
                stringBuilder.append("`").append(x).append("`,");
            });
            stringBuilder.deleteCharAt(stringBuilder.length() -1);
            stringBuilder.append(") USING BTREE");
        }
        //不区分音调
        stringBuilder.append(") ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ");
        if(StringUtils.isNotBlank(generateDevMain.getTableDescription())){
            stringBuilder.append("COMMENT='").append(generateDevMain.getTableDescription()).append("';");
        }
        return stringBuilder.toString();
    }

    /**
     * 修改表字段
     * @param generateDbDTO
     * @return
     */
    private List<String> updateColumnName(GenerateDbDTO generateDbDTO){
        List<String> sqlList = new ArrayList<>();
        generateDbDTO.getGenerateDevDetailList().stream().sorted(Comparator.comparing(GenerateDevDetail::getSortOrder)).forEachOrdered(x->{
            if(StringUtils.isNotBlank(x.getColumnName()) && StringUtils.isNotBlank(x.getOldColumnName())){
                //修改字段信息
                StringBuilder stringBuilder = new StringBuilder();
                //列名
                stringBuilder.append("`").append(x.getOldColumnName()).append("`").append(" ");
                //新列名
                stringBuilder.append("`").append(x.getColumnName()).append("`").append(" ");
                //有小数点单独判断
                if(GenerateMysqlType.doubleType.getCode().equals(x.getColumnType()) || GenerateMysqlType.BigDecimalType.getCode().equals(x.getColumnType())){
                    stringBuilder.append(GenerateMysqlType.getDescByCode(x.getColumnType())).append("(").append(x.getColumnLength()).append(",").append(x.getColumnPoint()).append(")").append(" ");
                }else {
                    stringBuilder.append(GenerateMysqlType.getDescByCode(x.getColumnType())).append("(").append(x.getColumnLength()).append(")").append(" ");
                }
                //是否可为空
                if(x.getIsNull() != 1){
                    stringBuilder.append("NOT NULL ");
                }
                //默认值
                if(StringUtils.isNotBlank(x.getColumnDef())){
                    stringBuilder.append("DEFAULT '").append(x.getColumnDef()).append("' ");
                }
                //列注释
                stringBuilder.append("COMMENT '").append(x.getColumnDesc()).append("'");
                sqlList.add("ALTER TABLE "+ generateDbDTO.getGenerateDevMain().getTableName() +" CHANGE " +stringBuilder +";");
            }
            if(StringUtils.isNotBlank(x.getColumnName()) && StringUtils.isBlank(x.getOldColumnName())){
                //添加的字段信息
                StringBuilder stringBuilder = new StringBuilder();
                //列名
                stringBuilder.append("`").append(x.getColumnName()).append("`").append(" ");
                //有小数点单独判断
                if(GenerateMysqlType.doubleType.getCode().equals(x.getColumnType()) || GenerateMysqlType.BigDecimalType.getCode().equals(x.getColumnType())){
                    stringBuilder.append(GenerateMysqlType.getDescByCode(x.getColumnType())).append("(").append(x.getColumnLength()).append(",").append(x.getColumnPoint()).append(")").append(" ");
                }else {
                    stringBuilder.append(GenerateMysqlType.getDescByCode(x.getColumnType())).append("(").append(x.getColumnLength()).append(")").append(" ");
                }
                //是否可为空
                if(x.getIsNull() != 1){
                    stringBuilder.append("NOT NULL ");
                }
                //默认值
                if(StringUtils.isNotBlank(x.getColumnDef())){
                    stringBuilder.append("DEFAULT '").append(x.getColumnDef()).append("' ");
                }
                //列注释
                stringBuilder.append("COMMENT '").append(x.getColumnDesc()).append("'");
                sqlList.add("ALTER TABLE "+ generateDbDTO.getGenerateDevMain().getTableName() +" ADD " +stringBuilder +";");

            }
            if(StringUtils.isBlank(x.getColumnName()) && StringUtils.isNotBlank(x.getOldColumnName())){
                //删除字段信息
                sqlList.add("ALTER TABLE "+ generateDbDTO.getGenerateDevMain().getTableName()+" DROP "+x.getOldColumnName()+";");
            }
        });
        return sqlList;
    }
}
